package com.kly.ai.app;

import cn.hutool.core.io.resource.ResourceUtil;
import com.kly.ai.advisor.MyLoggerAdvisor;
import com.kly.ai.advisor.ReReadingAdvisor;
import com.kly.ai.chatmemory.FileBasedChatMemory;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
import org.springframework.ai.chat.client.advisor.api.Advisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;

import java.util.List;

import static com.kly.ai.constants.FileConstant.MESSAGE_SAVE_DIR;
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;

/**
 * @author admin
 * @date 2025/5/28
 */

@Component
public class LoveApp {

    private String systemPrompt;
    private final ChatClient chatClient;

    @Resource
    private VectorStore vectorStore;

    @Resource
    private Advisor loadLoveDocumentsAdvisor;

    @Resource
    private ToolCallback[] allTools;

    // @Resource
    // @Lazy
    // private ToolCallbackProvider toolCallbackProvider;


    // 通过构造器注入ChatModel
    // public TeacherApp(ChatModel dashscopeChatModel) {
    //     InMemoryChatMemory chatMemory = new InMemoryChatMemory();
    //     this.chatClient = ChatClient.builder(dashscopeChatModel)
    //             .defaultSystem(systemPrompt)
    //             .defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory))
    //             .build();
    // }
    // 通过builder创建

    public LoveApp(ChatModel dashscopeChatModel) {
        // InMemoryChatMemory chatMemory = new InMemoryChatMemory();
        // 使用文件存储
        systemPrompt = ResourceUtil.readUtf8Str("prompt/system1.txt");
        System.out.println(systemPrompt);
        ChatMemory fileBasedChatMemory = new FileBasedChatMemory(MESSAGE_SAVE_DIR);
        this.chatClient = ChatClient
                .builder(dashscopeChatModel)
                .defaultAdvisors(new MessageChatMemoryAdvisor(fileBasedChatMemory))
                .build();
    }

    /**
     * 基础长对话
     *
     * @param conversationId
     * @param question
     * @return
     */
    public String callByCommon(String conversationId, String question) {
        ChatResponse response = chatClient
                .prompt()
                .user(question)
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversationId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
                .call()
                .chatResponse();

        return response.getResult().getOutput().getText();
    }

    /**
     * 基础长对话 Flux异步
     */
    public Flux<String> callByCommonFlux(String conversationId, String question) {
        Flux<String> content = chatClient
                .prompt()
                .user(question)
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversationId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
                .stream()
                .content();

        return content;
    }


    /**
     * 通过advisor 自定义日志
     *
     * @param conversationId
     * @param question
     * @return
     */
    public String callByAdvisor(String conversationId, String question) {
        ChatResponse response = chatClient
                .prompt()
                .user(question)
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversationId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
                .advisors(new MyLoggerAdvisor())
                .call()
                .chatResponse();

        return response.getResult().getOutput().getText();
    }

    record LoveReport(String title, List<String> suggestions) {
    }

    /**
     * 生成lovereport 生成entity对象
     *
     * @param conversationId
     * @param question
     * @return
     */
    public LoveReport getLoveReport(String conversationId, String question) {


        return chatClient
                .prompt()
                .user(question)
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversationId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
                .advisors(new MyLoggerAdvisor())
                .call()
                .entity(LoveReport.class);

    }

    /**
     * 使用rag 检索增强顾问 本地rag
     */
    public String callByLocalRags(String conversationId, String question) {
        ChatResponse chatResponse = chatClient.prompt()
                .user(question)
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversationId))
                .advisors(new MyLoggerAdvisor())
                // .advisors(new ReReadingAdvisor())
                .advisors(new QuestionAnswerAdvisor(vectorStore))
                .call()
                .chatResponse();
        return chatResponse.getResult().getOutput().getText();
    }

    /**
     * 使用rag 检索增强顾问 云端rag
     */
    public String callByCloudRags(String conversationId, String question) {
        ChatResponse chatResponse = chatClient.prompt()
                .user(question)
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversationId))
                .advisors(new MyLoggerAdvisor())
                // .advisors(new ReReadingAdvisor())
                .advisors(loadLoveDocumentsAdvisor)
                .call()
                .chatResponse();
        return chatResponse.getResult().getOutput().getText();
    }


    /**
     * 工具调用 tools
     */
    public String callByTool(String conversationId, String question) {
        ChatResponse chatResponse = chatClient.prompt()
                .user(question)
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversationId).param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
                .advisors(new MyLoggerAdvisor())
                .tools(allTools)
                .call()
                .chatResponse();
        return chatResponse.getResult().getOutput().getText();
    }


    /**
     * 调用mcps
     */
    public String callByMcps(String conversationId, String question) {
        ChatResponse chatResponse = chatClient.prompt()
                .user(question)
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversationId))
                .advisors(new MyLoggerAdvisor())
                .call()
                .chatResponse();
        return chatResponse.getResult().getOutput().getText();
    }


    /**
     * loveApp
     */
    public Flux<String> call(String conversationId, String question) {
        Flux<String> content = chatClient.prompt()
                .user(question)
                .system(systemPrompt)
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversationId))
                .advisors(new MyLoggerAdvisor())
                .advisors(new ReReadingAdvisor())
                .tools(allTools)
                .stream()
                .content();
        return content;
    }


}
